/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.inputmethod.pinyin;


import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
import android.view.animation.Animation.AnimationListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ViewFlipper;

import java.util.List;

import static com.android.inputmethod.pinyin.PinyinIME.TAG;

interface ArrowUpdater {
    void updateArrowStatus();
}


/**
 * Container used to host the two candidate views. When user drags on candidate
 * view, animation is used to dismiss the current candidate view and show a new
 * one. These two candidate views and their parent are hosted by this container.
 * <p>
 * Besides the candidate views, there are two arrow views to show the page
 * forward/backward arrows.
 * </p>
 */
public class CandidatesContainer extends RelativeLayout implements
        OnTouchListener , ArrowUpdater {
    /**
     * Alpha value to show an enabled arrow.
     */
    private static int ARROW_ALPHA_ENABLED = 0xff;

    /**
     * Alpha value to show an disabled arrow.
     */
    private static int ARROW_ALPHA_DISABLED = 0x40;



    /**
     * The right arrow button used to show next page.
     */
    private ImageButton mRightArrowBtn,mDropDownBtn;

    /**
     * Decoding result to show.
     */
    private List<Letter> mLetters;




    /**
     * Current page number in display.
     */
    private int mCurrentPage = -1;

    private boolean isShowTools = true;

    private HorizontalScrollView mCandidateScroll;
    private LinearLayout mToolLinearLayout;

    private ImageButton toolSetting,toolKeyBoard,toolEmoji,toolChat;

    private CandidateView mCandidateView;

    public CandidatesContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void initialize(CandidateViewListener cvListener, GestureDetector gestureDetector) {

        mRightArrowBtn = (ImageButton) findViewById(R.id.arrow_right_btn);
        mRightArrowBtn.setOnTouchListener(this);
        mCandidateView = (CandidateView)findViewById(R.id.candidate_view);
        mCandidateScroll = (HorizontalScrollView)findViewById(R.id.candidate_scrollview);
        mToolLinearLayout = (LinearLayout) findViewById(R.id.toolsView);
        if(toolSetting == null)
        {
            toolSetting = (ImageButton) findViewById(R.id.toolSetting);
            toolSetting.setOnTouchListener(this);
        }
        if(toolEmoji == null)
        {
            toolEmoji = (ImageButton) findViewById(R.id.toolEmoji);
            toolEmoji.setOnTouchListener(this);
        }
        if(toolKeyBoard == null)
        {
            toolKeyBoard = (ImageButton) findViewById(R.id.toolKeyBoard);
            toolKeyBoard.setOnTouchListener(this);
        }
        if(mDropDownBtn == null)
        {
            mDropDownBtn = (ImageButton) findViewById(R.id.drop_down_btn);
            mDropDownBtn.setOnTouchListener(this);
        }
        if(toolChat == null)
        {
            toolChat = (ImageButton) findViewById(R.id.toolChat);
            toolChat.setOnTouchListener(this);
        }
        mCandidateScroll.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mCandidateView.onTouchEventReal(event,mCandidateScroll.getScrollX());
                return false;
            }
        });

        invalidate();
        requestLayout();
        mCandidateView.initialize(this, gestureDetector,cvListener);

    }



    public void showCandidates(List<Letter> letters,
            boolean enableActiveHighlight) {
        if(PinyinIME.mImeState == PinyinIME.ImeState.STATE_IDLE)
        {
            if(toolSetting == null)
            {
                toolSetting = (ImageButton) findViewById(R.id.toolSetting);
                toolSetting.setOnTouchListener(this);
            }
            if(mDropDownBtn == null)
            {
                mDropDownBtn = (ImageButton) findViewById(R.id.drop_down_btn);
                mDropDownBtn.setOnTouchListener(this);
            }
            mToolLinearLayout.setVisibility(View.VISIBLE);
            mCandidateScroll.setVisibility(INVISIBLE);
            isShowTools = true;
        }else {
            mToolLinearLayout.setVisibility(View.GONE);
            mCandidateScroll.setVisibility(VISIBLE);
            isShowTools = false;
        }

        mLetters = letters;
        mCurrentPage = 0;

        if (PinyinIME.mImeState == PinyinIME.ImeState.STATE_IDLE) {
            showArrow(mRightArrowBtn, mDropDownBtn, false);
        } else {
            showArrow(mRightArrowBtn, mDropDownBtn, true);
        }

        mCandidateView.setDecodingInfo(letters);
        mCandidateScroll.scrollTo(0,0);
        mCandidateView.showPage(mCurrentPage, 0, enableActiveHighlight);

        updateArrowStatus();
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Environment env = Environment.getInstance();
        int measuredWidth = env.getScreenWidth();
        int measuredHeight = getPaddingTop();
        measuredHeight += env.getHeightForCandidates();
        widthMeasureSpec = MeasureSpec.makeMeasureSpec(measuredWidth,
                MeasureSpec.EXACTLY);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(measuredHeight,
                MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


    }

    public boolean pageForward() {

        mCandidateScroll.smoothScrollBy(getWidth() -mRightArrowBtn.getWidth() ,0);

        updateArrowStatus();
        return true;
    }


    public int getActiveCandiatePos() {
        return mCandidateView.getActiveCandiatePosInPage();
    }

    public void updateArrowStatus() {
        if (mCurrentPage < 0) return;
        boolean forwardEnabled = true;


        if (forwardEnabled) {
            enableArrow(mRightArrowBtn, true);
        } else {
            enableArrow(mRightArrowBtn, false);
        }
    }

    private void enableArrow(ImageButton arrowBtn, boolean enabled) {
        arrowBtn.setEnabled(enabled);
        if (enabled)
            arrowBtn.setAlpha(ARROW_ALPHA_ENABLED);
        else
            arrowBtn.setAlpha(ARROW_ALPHA_DISABLED);
    }

    private void showArrow(ImageButton arrowBtn,ImageButton dropDownBtn, boolean show) {
        if (show) {
            arrowBtn.setVisibility(View.VISIBLE);
            dropDownBtn.setVisibility(View.INVISIBLE);
        }
        else {
            arrowBtn.setVisibility(View.INVISIBLE);
            dropDownBtn.setVisibility(View.VISIBLE);
        }
    }

    PinyinIME pinyinIME;

    public void setServiceInstance(PinyinIME pinyinIME)
    {
        this.pinyinIME = pinyinIME;
    }
    View lastView;
    float lastX,lastY;
    float delta;
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            lastView = v;
            lastX = event.getRawX();
            lastY = event.getRawY();
            SoundManager.getInstance(getContext(),pinyinIME.getApplication()).playKeyDown();

        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            delta = v.getHeight()>v.getWidth()?v.getWidth():v.getHeight();
            delta /= 2;
            if(Math.abs(lastX-event.getRawX()) > delta
                    || Math.abs(lastY-event.getRawY())>delta)
                return false;
            if(v == lastView && v == mRightArrowBtn)
            {

                pageForward();
            }else if(v == lastView && v == mDropDownBtn)
            {
                if(pinyinIME != null) pinyinIME.requestHideSelf(0);
            }else if(v == lastView && v == toolSetting)
            {
                if(pinyinIME != null) pinyinIME.launchSettings();
            }else if(v == lastView && v == toolEmoji)
            {
                if(pinyinIME != null && pinyinIME.isInputViewShown()) {
                    if (pinyinIME.mImeState == PinyinIME.ImeState.STATE_INPUT)
                        pinyinIME.resetToIdleState();
                    if(pinyinIME.mInputModeSwitcher.state == pinyinIME.mInputModeSwitcher.lastState)
                        pinyinIME.mInputModeSwitcher.changeKeyBoard(InputModeSwitcher.LuaState.EMOJI,null);
                    else
                        pinyinIME.mInputModeSwitcher.changeKeyBoard(pinyinIME.mInputModeSwitcher.lastState,pinyinIME.mInputModeSwitcher.keyBoardState);
                    pinyinIME.mSkbContainer.updateInputMode();
                }
            }else if(v == lastView && v == toolKeyBoard)
            {
                if(pinyinIME != null && pinyinIME.isInputViewShown()) {
                    if(pinyinIME.mImeState == PinyinIME.ImeState.STATE_INPUT)
                        pinyinIME.resetToIdleState();
                    if(pinyinIME.mInputModeSwitcher.state == pinyinIME.mInputModeSwitcher.lastState)
                        pinyinIME.mInputModeSwitcher.changeKeyBoard(InputModeSwitcher.LuaState.SWITCH,null);
                    else
                        pinyinIME.mInputModeSwitcher.changeKeyBoard(pinyinIME.mInputModeSwitcher.lastState,pinyinIME.mInputModeSwitcher.keyBoardState);
                    pinyinIME.mSkbContainer.updateInputMode();
                };
            }else if(v == lastView && v == toolChat)
            {
                if(pinyinIME != null && pinyinIME.isInputViewShown()) {
                    if(pinyinIME.mImeState == PinyinIME.ImeState.STATE_INPUT)
                        pinyinIME.resetToIdleState();
                    if(pinyinIME.mInputModeSwitcher.state == pinyinIME.mInputModeSwitcher.lastState)
                        pinyinIME.mInputModeSwitcher.changeKeyBoard(InputModeSwitcher.LuaState.CHAT,null);
                    else
                        pinyinIME.mInputModeSwitcher.changeKeyBoard(pinyinIME.mInputModeSwitcher.lastState,pinyinIME.mInputModeSwitcher.keyBoardState);
                    pinyinIME.mSkbContainer.updateInputMode();
                };
            }
            mCandidateView.enableActiveHighlight(true);
        }

        return false;
    }


}
